﻿import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { message, notification } from 'antd';

// 错误处理方案： 错误类型
enum ErrorShowType {
  SILENT = 0,
  WARN_MESSAGE = 1,
  ERROR_MESSAGE = 2,
  NOTIFICATION = 3,
  REDIRECT = 9,
}

// 与后端约定的响应数据格式
interface ResponseStructure {
  success: boolean;
  data: any;
  code?: number;
  message?: string;
  errorCode?: number;
  errorMessage?: string;
  showType?: ErrorShowType;
}

/**
 * @name 错误处理
 * pro 自带的错误处理， 可以在这里做自己的改动
 * @doc https://umijs.org/docs/max/request#配置
 */
export const errorConfig: RequestConfig = {
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出
    errorThrower: (res) => {
      const { success, data, code, message: msg, errorCode, errorMessage, showType } =
        res as unknown as ResponseStructure;
      
      // 处理AI-Agent-Platform后端的错误格式
      if (code !== undefined && code !== 0) {
        const error: any = new Error(msg || '请求失败');
        error.name = 'BizError';
        error.info = { errorCode: code, errorMessage: msg, showType: ErrorShowType.ERROR_MESSAGE, data };
        throw error;
      }
      
      // 处理标准错误格式
      if (!success) {
        const error: any = new Error(errorMessage);
        error.name = 'BizError';
        error.info = { errorCode, errorMessage, showType, data };
        throw error; // 抛出自制的错误
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const errorInfo: ResponseStructure | undefined = error.info;
        if (errorInfo) {
          const { errorMessage, errorCode } = errorInfo;
          const displayMessage = errorMessage || error.message || '未知错误';
          
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
              break;
            case ErrorShowType.WARN_MESSAGE:
              message.warning(displayMessage);
              break;
            case ErrorShowType.ERROR_MESSAGE:
              message.error(displayMessage);
              break;
            case ErrorShowType.NOTIFICATION:
              notification.open({
                description: displayMessage,
                message: errorCode,
              });
              break;
            case ErrorShowType.REDIRECT:
              // TODO: redirect
              break;
            default:
              message.error(displayMessage);
          }
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        const responseData = error.response.data;
        const errorMsg = responseData?.message || responseData?.errorMessage || `请求错误 (${error.response.status})`;
        message.error(errorMsg);
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('服务器无响应，请重试');
      } else {
        // 发送请求时出了点问题
        message.error('请求错误，请重试');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      // 获取token
      const token = localStorage.getItem('token');
      
      // 如果有token，添加到请求头
      if (token) {
        // 确保headers对象存在
        const headers = config.headers || {};
        headers['Authorization'] = `Bearer ${token}`;
        config.headers = headers;
      }
      
      // 拦截请求配置，进行个性化处理。
      return config;
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response) => {
      // 拦截响应数据，进行个性化处理
      const { data } = response;

      // 使用类型断言来处理自定义响应
      try {
        // 检查自定义后端响应格式
        if (data && typeof data === 'object' && 'code' in data && data.code !== 0) {
          // 使用类型断言处理
          const apiResponse = data as any;
          const errorMsg = apiResponse.message || apiResponse.errorMessage || '请求失败';
          message.error(errorMsg);
        }
        
        // 检查标准响应格式
        if (data && typeof data === 'object' && 'success' in data && data.success === false) {
          // 使用类型断言处理
          const apiResponse = data as any;
          const errorMsg = apiResponse.errorMessage || apiResponse.message || '请求失败';
          message.error(errorMsg);
      }
      } catch (error) {
        // 忽略拦截器错误
        console.error('Response interceptor error:', error);
      }
      
      return response;
    },
  ],
};
